using System; using System.Collections.Generic; using System.Linq; using System.Text; using Roslyn.Compilers; using Roslyn.Compilers.CSharp; using SymbolicComputation; namespace Sym.Test { public class RandomEquationGenerator { static Random random = new Random(); public enum enumBinaryKinds { Add, Subtract, Multiply, Divide } public enum enumExpressionType { NoEqualSign, EqualSign } List<SyntaxKind> binaryKinds = CreateBinaryKinds(); Func<SyntaxNode> CreateNodeFunction; public String CreateExpression(int layers, enumExpressionType expressionType) { CreateNodeFunction = RandomPowerNode; //CreateNodeFunction = RandomBinaryAndParanthesisNode; //CreateNodeFunction = RandomNode; int layerIndex; SyntaxNode root = null; List<SyntaxNode> branches; StartOver: root = CreateNodeFunction(); for (layerIndex = 1; layerIndex < layers; layerIndex++) { branches = ChildStringBranches(root); root = Miscellaneous.ReplaceNodes(root, branches, x => RandomNode(x)); } branches = ChildStringBranches(root); root = Miscellaneous.ReplaceNodes(root, branches, x => RandomNumericNode(x,-2,4)); if (expressionType == enumExpressionType.EqualSign) { SyntaxNode equationRoot = EquationNode(); Double val = RoslynEval.ScriptEval.Evaluate(root.ToString()); if (Double.IsNaN(val) == true) { goto StartOver; } if (Double.IsNegativeInfinity(val) == true) { goto StartOver; } if (Double.IsPositiveInfinity(val) == true) { goto StartOver; } if ( val > 10000 | val<-10000 | val == 0 | val == 1 ) { goto StartOver; } SyntaxNode lhs = Miscellaneous.EquationToSyntaxNode(val.ToString() + "d"); branches = equationRoot.ChildNodes().ToList(); equationRoot = equationRoot.ReplaceNode(branches[0], lhs); branches = equationRoot.ChildNodes().ToList(); equationRoot = equationRoot.ReplaceNode(branches[1], root); return equationRoot.ToString(); } return root.ToString(); } public SyntaxNode RandomNode(SyntaxNode oldNode) { return Transform.WrapNodeInBrackets(oldNode.Parent, CreateNodeFunction()); } public SyntaxNode RandomNumericNode(SyntaxNode oldNode,Double lBound,Double range) { return Transform.WrapNodeInBrackets(oldNode.Parent, RandomNumericNode(lBound,range)); } public static List<SyntaxNode> ChildStringBranches(SyntaxNode root) { List<SyntaxNode> branches = root.DescendentNodesAndSelf().ToList(); var childBranches = from n in branches where n.ToString() == "child" select n; return childBranches.ToList(); } public SyntaxNode RandomNumericNode(Double lBound,Double range) { String eq = Convert.ToString(random.NextDouble() * range + lBound)+"d"; //String eq = Convert.ToString(random.NextDouble() * range) + "d"; SyntaxNode sn = Miscellaneous.EquationToSyntaxNode(eq); return sn; } public SyntaxNode RandomBinaryAndParanthesisNode() { double num = random.NextDouble(); if (num > 0 & num <= .75) { return RandomBinaryNode(); } else if (num > .75 & num <= 1) { return ParanthesesNode(); } return null; } public SyntaxNode RandomPowerNode() { double num = random.NextDouble(); if (num > 0 & num <= .7) { return RandomBinaryNode(); } else if (num > .7 & num <= .8) { return ParanthesesNode(); } else if (num > .1 & num <= 1) { return RandomPowerNode(2); } return null; } public SyntaxNode RandomNode() { double num = random.NextDouble(); if (num >0 & num <=.5) { return RandomBinaryNode(); } else if (num > .5 & num <= .6) { return ParanthesesNode(); } else if (num > .6 & num <= .7) { return RandomPowerNode(2); } else if (num > .7 & num <= 1) { return RandomTrigonometryNode(1); } return null; } public SyntaxNode RandomBinaryNode() { int num = random.Next(4); //fix divisions return CreateBinaryNode(binaryKinds[num]); } public static SyntaxNode ParanthesesNode() { return Miscellaneous.EquationToSyntaxNode("(child)"); } public static SyntaxNode RandomPowerNode(double range) { return Miscellaneous.EquationToSyntaxNode("Math.Pow(child,child);"); } public static SyntaxNode RandomTrigonometryNode(double range) { String[] trigNames = { "Sin", "Cos", "Tan", "Asin", "Acos", "Atan" }; int trigNameIndex = random.Next(6); String trigName = "Math." + trigNames[trigNameIndex]; SyntaxNode lOut = Miscellaneous.EquationToSyntaxNode(trigName + "(child);"); return lOut; } public static List<SyntaxKind> CreateBinaryKinds() { List<SyntaxKind> lOut = new List<SyntaxKind>(); lOut.Add(SyntaxKind.AddExpression); lOut.Add(SyntaxKind.SubtractExpression); lOut.Add(SyntaxKind.MultiplyExpression); lOut.Add(SyntaxKind.DivideExpression); return lOut; } private static SyntaxNode CreateBinaryNode(SyntaxKind inKind) { ExpressionSyntax left = Syntax.IdentifierName("child"); ExpressionSyntax right = Syntax.IdentifierName("child"); SyntaxToken st = new SyntaxToken(); return Syntax.BinaryExpression(inKind, left, st, right); } public static SyntaxNode EquationNode() { return Miscellaneous.EquationToSyntaxNode("child==child"); } } }